`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/01 11:29:37
// Design Name: 
// Module Name: UART_Unit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module UART_Unit(
    input   wire    clk_50M,
    input   wire    clk,
    input   wire    clr,
    input   wire    rxd,  //直连串口接收端
    output  wire    txd,  //直连串口发送端
    
    input   wire    TxD_valid,
    output  wire    TxD_ready,
    input   wire    [7:0]   TxD_din,

    input   wire    RxD_ready,
    output  wire    RxD_valid,
    output  wire    [7:0]   RxD_dout
    );
    // 0xBFD003F8 数据收发接口
    //0xBFD003FC [1]:recived [0]:IDLE  

    parameter ClkFrequency = 50000000;// 50MHz
	parameter Baud = 9600;

    wire RxD_data_ready;
    wire RxD_clear;
    wire [7:0] RxD_data;

    wire TxD_busy;
    wire TxD_start;
    wire [7:0] TxD_data;

    wire RXD_FIFO_wr_en;
    wire RXD_FIFO_full;
    wire [7:0] RXD_FIFO_din;
    wire RXD_FIFO_rd_en;
    wire RXD_FIFO_empty;
    wire [7:0] RXD_FIFO_dout;

    wire TXD_FIFO_wr_en;
    wire TXD_FIFO_full;
    wire [7:0] TXD_FIFO_din;
    wire TXD_FIFO_rd_en;
    wire TXD_FIFO_empty;
    wire [7:0] TXD_FIFO_dout;

    assign TxD_ready = ~TXD_FIFO_full;
    assign RxD_valid = ~RXD_FIFO_empty;
    assign RxD_dout = RXD_FIFO_dout;
   

    assign RxD_clear = (RxD_data_ready&&(~RXD_FIFO_full))||clr;//收到数据，且FIFO没满，就能继续装
     
    assign TxD_start = (~TxD_busy)&&(~TXD_FIFO_empty);//FIFO不空，且不忙的时候就发送
    assign TxD_data = TXD_FIFO_dout;//来自FIFO的数据

    assign RXD_FIFO_wr_en = RxD_clear;//清空的同时写入
    assign RXD_FIFO_din = RxD_data;//接收端的数据   
    assign RXD_FIFO_rd_en = RxD_ready;
    
    assign TXD_FIFO_wr_en = TxD_valid;
    assign TXD_FIFO_din   = TxD_din; 
    assign TXD_FIFO_rd_en = TxD_start;//进行发送

    wire [9:0]  RXD_FIFO_rd_data_count,RXD_FIFO_wr_data_count,TXD_FIFO_rd_data_count,TXD_FIFO_wr_data_count;
    async_receiver #(.ClkFrequency(50000000),.Baud(9600)) //接收模块，9600无检验位
    uart_r(
        .clk(clk_50M),                       //外部时钟信号
        .RxD(rxd),                           //外部串行信号输入
        .RxD_data_ready(RxD_data_ready),  //数据接收到标志
        .RxD_clear(RxD_clear),       //清除接收标志
        .RxD_data(RxD_data)             //接收到的一字节数据
    );
    async_transmitter #(.ClkFrequency(50000000),.Baud(9600)) //发送模块，9600无检验位
    uart_t(
        .clk(clk_50M),                  //外部时钟信号
        .TxD(txd),                      //串行信号输出
        .TxD_busy(TxD_busy),       //发送器忙状态指示
        .TxD_start(TxD_start),    //开始发送信号
        .TxD_data(TxD_data)        //待发送的数据
    );


    fifo RXD_FIFO (
        .rst(clr),                  // input wire rst
        .wr_clk(clk_50M),            // input wire wr_clk
        .wr_en(RXD_FIFO_wr_en),              // input wire wr_en
        .din(RXD_FIFO_din),                  // input wire [7 : 0] din
        .full(RXD_FIFO_full),                // output wire full


        .rd_clk(clk),            // input wire rd_clk
        .rd_en(RXD_FIFO_rd_en),              // input wire rd_en
        .dout(RXD_FIFO_dout),                // output wire [7 : 0] dout
        .empty(RXD_FIFO_empty),              // output wire empty
        .rd_data_count(RXD_FIFO_rd_data_count),  // output wire [9 : 0] rd_data_count
        .wr_data_count(RXD_FIFO_wr_data_count),  // output wire [9 : 0] wr_data_count
        
        .wr_rst_busy(),  // output wire wr_rst_busy
        .rd_rst_busy()  // output wire rd_rst_busy
        );
        fifo TXD_FIFO (
        .rst(clr),                  // input wire rst
        .wr_clk(clk),            // input wire wr_clk
        .wr_en(TXD_FIFO_wr_en),              // input wire wr_en
        .din(TXD_FIFO_din),                  // input wire [7 : 0] din
        .full(TXD_FIFO_full),                // output wire full


        .rd_clk(clk_50M),            // input wire rd_clk
        .rd_en(TXD_FIFO_rd_en),              // input wire rd_en
        .dout(TXD_FIFO_dout),                // output wire [7 : 0] dout
        .empty(TXD_FIFO_empty),              // output wire empty
        .rd_data_count(TXD_FIFO_rd_data_count),  // output wire [9 : 0] rd_data_count
        .wr_data_count(TXD_FIFO_wr_data_count),  // output wire [9 : 0] wr_data_count
        
        .wr_rst_busy(),  // output wire wr_rst_busy
        .rd_rst_busy()  // output wire rd_rst_busy
        );
    //////////////////////////////////////////////////////////////////////////////////
endmodule
